import { ref, getCurrentInstance, reactive } from "vue";
import type { Ref } from "vue";
import { useDeviceStore } from "@/stores/device";
import { useI18n } from "vue-i18n";
import { getDevicePlans, getDeviceMapsApi } from "@/service/index";
import { nextTick } from "vue";
interface ZoneDisplay {
	url: string;
	x: number;
	y: number;
	type: string;
	path?: string;
}
export const useDevice = () => {
	const { t } = useI18n();
	const deviceStore = useDeviceStore();
	const device_sn = ref("");
	const hasDefaultMap = ref(false);
	// const showMapInfo = ref({
	// 	mapUrl: "",
	// 	mapYaml: "",
	// });
	const isLoading = ref(false);
	const instance: any = getCurrentInstance();
	// 获取设备地图
	const getDeviceMaps = async (sn: string, type: string) => {
		// if (isLoading.value) return; // 避免重复调用
		// isLoading.value = true;
		device_sn.value = sn;
		try {
			const { data } = await getDeviceMapsApi({ device_sn: sn });
			if (!data?.code && data?.data?.vcu_maps?.length > 0) {
				const maps = [...data.data.vcu_maps].sort(
					(a, b) =>
						(b.property === 1 ? 1 : 0) - (a.property === 1 ? 1 : 0)
				);
				deviceStore.setDeviceMapList(maps);
				if (type != "manage") {
					hasDefaultMap.value = maps.some(
						(item) => item.property === 1
					);
					if (hasDefaultMap.value) {
						const defaultMap =
							maps.find((item) => item.property === 1) || maps[0];
						deviceStore.defaultDeviceMap = defaultMap;
						await getPlanList();
					} else {
						const mapStore = useUniversalStorage<string>(
							"Map_Store",
							null
						);
						mapStore.value = null;
						instance.proxy.$message(
							t("device.noDefaultMap"),
							"warning"
						);
					}
					if (deviceStore.defaultDeviceMap?.layer_url) {
						await getSettingsUrl(
							deviceStore.defaultDeviceMap.layer_url
						);
						deviceStore.setUurl(
							deviceStore.defaultDeviceMap.layer_url
						);
					}
				} else {
					deviceStore.clearStore();
				}
			} else {
				deviceStore.setDeviceMapList([]);
				instance.proxy.$message(t("device.noMap"), "error");
			}
		} catch (error) {
			console.error("获取设备地图失败:", error);
			instance.proxy.$message("networkError", "error");
		}
	};

	// 获取设置URL
	const getSettingsUrl = async (url: string) => {
		try {
			const response = await uni.request({
				url,
				method: "GET",
			});
			deviceStore.settingJson = response.data;
			if (deviceStore.settingJson?.rain_shelter?.point) {
				deviceStore.shopList =
					deviceStore.settingJson.rain_shelter.point;
			}
		} catch (error) {
			console.error("获取设置URL失败:", error);
		}
	};

	// 获取计划列表
	const getPlanList = async (deviceSn?: string) => {
		if (!deviceStore.defaultDeviceMap) return;
		try {
			const { data } = await getDevicePlans({
				device_sn: deviceSn || device_sn.value,
				map_id: deviceStore.defaultDeviceMap.map_info.map_id,
			});
			if (data.data.plans.length > 0) {
				deviceStore.planList = data.data.plans.filter(
					(item) => item.pattern === 3
				);
				if (deviceStore.planList.length > 0) {
					deviceStore.defaultPlan =
						deviceStore.planList.find((item) => item.property) ||
						deviceStore.planList[0];
					if (deviceStore.defaultPlan) {
						switch (deviceStore.defaultPlan.pattern) {
							case 1:
								getZonesList(
									deviceStore.defaultPlan.zone_pattern
										?.zones || []
								);
								break;
							case 2:
								getTrackList(
									deviceStore.defaultPlan.track_pattern
								);
								break;
							case 3:
								getSelfPattern(
									deviceStore.defaultPlan.self_pattern
								);
								break;
						}
					}
				}
			} else {
				deviceStore.planList = [];
			}
		} catch (error) {
			console.error("获取计划列表失败:", error);
		}
	};

	// 计算显示分区地图
	const getZonesList = (
		arr: Array<{ zone_id: string; mode: string }> = []
	) => {
		if (!deviceStore.defaultDeviceMap) return;
		deviceStore.zonesList = arr.reduce<ZoneDisplay[]>((acc, item) => {
			const zone = deviceStore.defaultDeviceMap?.zone_info.zones.find(
				(z) => z.zone_id === item.zone_id
			);
			if (zone) {
				const doc = zone.zone_docs.find((d) =>
					d.name?.includes(item.mode)
				);
				if (doc) {
					acc.push({
						url: zone.zone_docs[0].oss_url,
						x: zone.rect[0],
						y: zone.rect[1],
						type: "csv",
						path: doc.oss_url,
					});
				}
			}
			return acc;
		}, []);
	};

	// 轨迹跟踪显示地图及路径
	const getTrackList = (pattern?: { path_id: string }) => {
		if (!pattern || !deviceStore.defaultDeviceMap) return;

		const path = deviceStore.defaultDeviceMap.path_infos.find(
			(p) => p.path_id === pattern.path_id
		);

		if (path) {
			deviceStore.zonesList = [
				{
					url: path.path_docs[0].oss_url,
					x: 0,
					y: 0,
					type: "csv",
					path: path.path_docs[0].oss_url,
				},
			];
		}
	};

	// 获取自定义模式
	const getSelfPattern = (pattern?: {
		tasks: Array<{
			task_type: string;
			path_id?: string;
			zone_id?: string;
		}>;
	}) => {
		if (!pattern || !deviceStore.defaultDeviceMap) return;
		deviceStore.zonesList = pattern.tasks.reduce<ZoneDisplay[]>(
			(acc, task) => {
				if (
					task.task_type === "manual" ||
					task.task_type === "strong_edge"
				) {
					if (task.path_id) {
						const path =
							deviceStore.defaultDeviceMap?.path_infos.find(
								(p) => p.path_id === task.path_id
							);

						if (path) {
							acc.push({
								url: path.path_docs[0].oss_url,
								x: 0,
								y: 0,
								type: "csv",
								path: path.path_docs[0].oss_url,
							});
						}
					}
				} else if (task.zone_id) {
					const zone =
						deviceStore.defaultDeviceMap?.zone_info.zones.find(
							(z) => z.zone_id === task.zone_id
						);

					if (zone) {
						const doc = zone.zone_docs.find((d) =>
							d.name?.includes(task.task_type)
						);

						if (doc) {
							acc.push({
								url: zone.zone_docs[0].oss_url,
								x: zone.rect[0],
								y: zone.rect[1],
								type: "csv",
								path: doc.oss_url,
							});
						}
					}
				}
				return acc;
			},
			[]
		);
	};

	return {
		hasDefaultMap,
		getDeviceMaps,
		getSettingsUrl,
		getPlanList,
		getZonesList,
		getTrackList,
		getSelfPattern,
	};
};

export const useMapImage = () => {
	// 响应式数据
	const mapImageInfo: Ref<MapImageInfo> = ref({
		scale: 1,
		left: 0,
		top: 0,
		mapUrl: "",
		width: 0,
		height: 0,
		original: {
			width: 0,
			height: 0,
		},
		realScale: 0,
	});
	const container: Ref<ContainerSize> = ref({ width: 0, height: 0 });
	const scaleWidth = ref(1200);
	const mapUrl = ref("");
	const deviceStore = useDeviceStore();
	const selShopPosition = ref();
	// 状态管理
	let origin: Origin | string = [0, 0];
	let resolution: number = 1;
	let pivotPosX: number = 0;
	let pivotPosY: number = 0;
	const posX = useUniversalStorage("pivotPosX", 0);
	const posY = useUniversalStorage("pivotPoY", 0);
	const resolutionStore = useUniversalStorage("resolution", 1);
	const isLoading = ref(false);
	// 响应式状态
	const selShopStyle = reactive<ShopStyle>({
		left: "0px",
		top: "0px",
		width: "0px",
		transform: "",
	});
	const positionIconStyle = reactive<ShopStyle>({
		left: "0px",
		top: "0px",
		width: "0px",
		transform: "",
	});
	// 压缩图片方法
	const compressImage = async (
		src: string,
		quality = 40
	): Promise<string> => {
		if (!src) return src;
		return new Promise((resolve, reject) => {
			uni.getImageInfo({
				src,
				success: (res) => {
					// APP端才需要压缩
					// #ifdef APP-PLUS
					const max = Math.max(res.width, res.height);
					if (max < 2000) return resolve(src);

					let scale = "50%";
					if (max > 2000) scale = "50%";
					if (max > 5000) scale = "40%";
					if (max > 10000) scale = "35%";

					uni.compressImage({
						src: res.path,
						quality,
						width: scale,
						height: scale,
						success: (compressed) =>
							resolve(compressed.tempFilePath),
						fail: (err) => {
							console.error("压缩失败:", err);
							reject(src);
						},
					});
					// #endif

					// H5端直接返回原图
					// #ifdef H5
					resolve(src);
					// #endif
				},
				fail: (err) => {
					console.error("获取图片信息失败:", err);
					reject(src);
				},
			});
		});
	};

	// 获取地图图片信息
	const getNewMapImg = async (url: string) => {
		if (isLoading.value) return; // 避免重复调用
		isLoading.value = true;
		mapUrl.value = url;
		try {
			const compressedUrl = await compressImage(mapUrl.value);
			// 获取压缩后的图片路径
			uni.getImageInfo({
				src: compressedUrl,
				success: (image) => {
					mapImageInfo.value.mapUrl = image.path;
				},
			});
			// 获取原始图片尺寸
			uni.getImageInfo({
				src: mapUrl.value,
				success: (image) => {
					mapImageInfo.value.original = {
						width: image.width,
						height: image.height,
					};
					const posX = useUniversalStorage("pivotPosX", 0);
					posX.value = image.width;
					const posY = useUniversalStorage("pivotPoY", 0);
					posY.value = image.height;
					if (
						mapImageInfo.value.scale &&
						mapImageInfo.value.scale !== 1
					) {
						scaleWidth.value = 600; // 重置基础宽度
					}

					// iOS平台特殊处理
					if (uni.getSystemInfoSync().platform == "ios") {
						scaleWidth.value *= 1.5;
					}
					calculateImageSize(image);
				},
			});
		} catch (error) {
			console.error("获取地图图片失败:", error);
		}
	};
	// 获取配置
	const getConfig = (): void => {
		try {
			const orginStore = useUniversalStorage("origin", [0, 0]);
			origin = orginStore.value || [0, 0];
			resolution = Number(resolutionStore.value) || 1;
			pivotPosX = Number(posX.value) || 0;
			pivotPosY = Number(posY.value) || 0;

			// 类型校验
			if (typeof origin === "string") {
				origin = JSON.parse(origin) as Origin;
			}
		} catch (error) {
			console.error("配置加载失败:", error);
			// 设置默认值
			origin = [0, 0];
			resolution = 1;
			pivotPosX = 0;
			pivotPosY = 0;
		}
	};

	// 坐标转换（带节流）
	const backPointChange = (point: Point): Point => {
		getConfig();
		// 类型断言确保 origin 是数组
		const originArray = origin as Origin;
		const coorY = Math.round(pivotPosY * resolution * 1000) / 1000;
		const x = (point.x - originArray[0]) / resolution;
		const y = (coorY - (point.y - originArray[1])) / resolution;

		return { x, y };
	};

	const getSelShopVal = (val: any) => {
		if (!val || JSON.stringify(val) === "{}") return;

		const pos = backPointChange({
			x: val[0],
			y: val[1],
		});
		const angle = (val[2] * 180) / Math.PI;

		Object.assign(positionIconStyle, {
			left: `${pos.x * mapImageInfo.value.realScale}px`,
			top: `${pos.y * mapImageInfo.value.realScale}px`,
			width: calculateIconSize(1),
			transform: `translate(-50%, -50%) rotate(${90 - angle}deg)`,
		});
	};
	// 计算图片尺寸和比例
	const calculateImageSize = (image: UniApp.GetImageInfoSuccessData) => {
		const width = scaleWidth.value;
		const scaleW = width / mapImageInfo.value.original.width;
		mapImageInfo.value = {
			...mapImageInfo.value,
			width,
			height: image.height * scaleW,
			realScale: scaleW,
		};
		// getSelShopVal(deviceStore.devicePosition);
		if (deviceStore.zonesList.length) {
			getNewZonesImg(deviceStore.zonesList, 0);
		}
		calculateMargin();
	};
	const getNewZonesImg = async (arr: ZoneDisplay[], num: number) => {
		const newImgs: any[] = [];
		for (const item of arr) {
			try {
				const image = await new Promise<UniApp.GetImageInfoSuccessData>(
					(resolve, reject) => {
						uni.getImageInfo({
							src: item.url,
							success: resolve,
							fail: reject,
						});
					}
				);
				const realScale =
					(image.width * mapImageInfo.value.realScale) / image.width;
				newImgs.push({
					...item,
					originalWidth: image.width,
					originalHeight: image.height,
					width: image.width * mapImageInfo.value.realScale,
					height: image.height * realScale,
					realScale,
				});
			} catch (error) {
				console.error(`获取分区图片 ${item.url} 失败:`, error);
			}
		}
		if (num === 0) {
			deviceStore.zonesList = newImgs || [];
		} else {
			deviceStore.selZone = newImgs || [];
		}
	};

	// 计算边距使图片居中
	const calculateMargin = () => {
		uni.createSelectorQuery()
			.select(".main")
			.boundingClientRect((data) => {
				if (!data) return;
				container.value = {
					width: data.width,
					height: data.height,
				};
				const newMapInfo = { ...mapImageInfo.value };
				// 水平居中
				if (newMapInfo.width > data.width) {
					newMapInfo.left =
						(newMapInfo.width / 2 - data.width / 2) * -1;
				}
				// 垂直居中
				if (newMapInfo.height > data.height) {
					newMapInfo.top =
						(newMapInfo.height / 2 - data.height / 2) * -1;
				}
				if (newMapInfo.scale && newMapInfo.scale !== 1) {
					const scaleRatio = newMapInfo.width / data.width;

					if (newMapInfo.width > data.width) {
						newMapInfo.left =
							(newMapInfo.width / 2 - data.width / 2) * -1 +
							newMapInfo.width / scaleRatio;
					}
					if (newMapInfo.height > data.height) {
						newMapInfo.top =
							(newMapInfo.height / 2 - data.height / 2) * -1;
					}
				}
				mapImageInfo.value = newMapInfo;
			})
			.exec();
	};
	const touchType = ref(0); // 0-无 1-缩放 2-拖动
	const slideType = ref(0);
	const firstTouches = ref<TouchState>({});
	const firstScale = ref(1);
	const hypot1 = ref(0);

	// 计算两点间距离（欧几里得距离）
	const getDistance = (one: TouchPoint, two: TouchPoint): number => {
		return Math.hypot(
			Math.abs(one.clientX - two.clientX),
			Math.abs(one.clientY - two.clientY)
		);
	};
	// 处理触摸移动事件
	const handleTouchmove = (e: TouchEvent) => {
		e.preventDefault();
		const touches = e.touches;
		// 双指缩放
		if (touches.length === 2) {
			handlePinchZoom(touches);
		}
		// 单指拖动
		else {
			handleSingleDrag(touches[0]);
		}
	};
	// 双指缩放处理
	const handlePinchZoom = (touches: TouchList) => {
		if (touchType.value !== 1) {
			initPinchZoomState(touches);
			return;
		}
		const hypot2 = getDistance(touches[0], touches[1]);
		const newScale = Number((hypot2 / hypot1.value).toFixed(2));
		const scale = mathRound(firstScale.value * newScale);
		if (scale > 0.05 && scale < 50) {
			updateMapScale(newScale, scale);
		}
		if (scale > 0.1 && scale < 10) {
			selShopStyle.width = calculateIconSize(scale);
			positionIconStyle.width = calculateIconSize(scale);
		}
	};

	// 初始化缩放状态
	const initPinchZoomState = (touches: TouchList) => {
		touchType.value = 1;
		firstScale.value = mapImageInfo.value.scale;
		Object.assign(firstTouches.value, {
			top: mapImageInfo.value.top,
			left: mapImageInfo.value.left,
			width: mapImageInfo.value.width,
			height: mapImageInfo.value.height,
		});
		hypot1.value = getDistance(touches[0], touches[1]);
	};

	// 更新地图缩放状态
	const updateMapScale = (ratio: number, scale: number) => {
		mapImageInfo.value.top = mathRound(
			(firstTouches.value.top || 0) * ratio
		);
		mapImageInfo.value.left = mathRound(
			(firstTouches.value.left || 0) * ratio
		);
		mapImageInfo.value.scale = scale;
	};

	// 单指拖动处理
	const handleSingleDrag = (touch: TouchPoint) => {
		if (slideType.value !== 1) {
			slideType.value = 1;
			Object.assign(firstTouches.value, touch);
			return;
		}

		const gapX = touch.clientX - (firstTouches.value.clientX || 0);
		const gapY = touch.clientY - (firstTouches.value.clientY || 0);
		Object.assign(firstTouches.value, touch);

		mapImageInfo.value.left = mathRound(
			(mapImageInfo.value.left || 0) + gapX
		);
		mapImageInfo.value.top = mathRound(
			(mapImageInfo.value.top || 0) + gapY
		);
	};

	// 触摸结束处理
	const handleTouchend = (e: TouchEvent) => {
		touchType.value = 0;
		if (!e.touches || e.touches.length === 0) {
			resetTouchState();
		}
	};

	// 重置触摸状态
	const resetTouchState = () => {
		firstTouches.value = {};
		slideType.value = 0;
	};

	// 保留两位小数
	const mathRound = (num: number): number => {
		return Math.round(num * 100) / 100;
	};

	// 计算图标尺寸
	const calculateIconSize = (scale: number): string => {
		const baseSize = 120;
		const scaleInt = Math.floor(scale);

		if (scale > 5) {
			return `${(baseSize * 5) / scale / 3}rpx`;
		} else if (scale > 1) {
			return `${(baseSize * scaleInt) / scale / scaleInt}rpx`;
		} else {
			return `${96 / scale}rpx`;
		}
	};
	const getPos = (val: any) => {
		getSelShopVal(val);
	};

	return {
		getNewMapImg,
		mapImageInfo,
		handleTouchmove,
		handleTouchend,
		positionIconStyle,
		selShopStyle,
		getPos,
		getNewZonesImg,
	};
};

export default {
	useDevice,
	useMapImage,
};
